package cn.ys.base.config;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 在某些特殊的情况下，Bean需要实现某个功能，但该功能必须借助于Spring容器才能实现，
 * 此时就必须让该Bean先获取Spring容器，然后借助于Spring容器实现该功能。
 * 为了让Bean获取它所在的Spring容器，可以让该Bean实现ApplicationContextAware接口。
 * ApplicationContextAware 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法。
 * 在ApplicationContextAware的实现类中，就可以通过这个上下文环境对象得到Spring容器中的Bean。
 * 看到—Aware就知道是干什么的了，就是属性注入的，
 * 但是这个ApplicationContextAware的不同地方在于，
 * 实现了这个接口的bean，当spring容器初始化的时候，会自动的将ApplicationContext注入进来。
 *
 * 应用上下文即是Spring容器的一种抽象化表述；
 * 而我们常见的ApplicationContext本质上说就是一个维护Bean定义以及对象之间协作关系的高级接口。
 * Spring的核心是容器，而容器并不唯一，框架本身就提供了很多个容器的实现，
 * 大概分为两种类型：
 *      一种是不常用的BeanFactory，这是最简单的容器，只能提供基本的DI功能；
 *      还有一种就是继承了BeanFactory后派生而来的应用上下文，其抽象接口也就是上面提到的的ApplicationContext，
 *          它能提供更多企业级的服务，例如解析配置文本信息等等，这也是应用上下文实例对象最常见的应用场景。
 *          有了上下文对象，我们就能向容器注册需要Spring管理的对象了。
 *          对于上下文抽象接口，Spring也为我们提供了多种类型的容器实现，供我们在不同的应用场景选择:
 *          ① AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义，适用于java注解的方式；
 *          ② ClassPathXmlApplicationContext：从类路径下的一个或多个xml配置文件中加载上下文定义，适用于xml配置的方式；
 *          ③ FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义，也就是说系统盘符中加载xml配置文件；
 *          ④ AnnotationConfigWebApplicationContext:专门为web应用准备的，适用于注解方式；
 *          ⑤ XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义，适用于xml配置方式。
 *
 *
 * Spring上下文是一个抽象的概念。
 * 简单点理解，就是将需要Spring IoC容器帮我们管理的对象（Spring中我们称对象为bean），
 *      bean 与 bean之间的协作关系，基于xml 或 Java注解的形式配置好，然后通过Spring应用上下文对象将其加载进Spring IoC容器中，
 *      这样容器就能给我们提供我们想要的对象管理服务。
 * 通俗点理解，
 *      就是我们需要一个对象，来将Spring配置文件中配置好的bean关系，加载到Spring IoC容器中，而Spring应用上下文就充当了这样的角色。
 * 所以我们可以说Spring上下文，就是将需要spring帮我们管理的对象加载到Spring IoC容器中的一种容器对象。
 * */

// 标注Spring管理的Bean，
// 标注一个类为Spring容器的Bean，
// 把普通pojo实例化到spring容器中，相当于配置文件中的<bean id="" class=""/>
// 实现bean的注入
@Component
public class SpringUtilConfig implements ApplicationContextAware {

    // 上下文对象
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getApplicationContext(){
        return context;
    }
}
